package work.huangxin.share.controller.admin;

import com.fasterxml.jackson.databind.ser.Serializers;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Strings;
import io.minio.errors.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import work.huangxin.share.domain.admin.UserAdminSys;
import work.huangxin.share.domain.other.WXSessionModel;
import work.huangxin.share.domain.sechand.SechandBuyGoods;
import work.huangxin.share.domain.sechand.SechandGoods;
import work.huangxin.share.domain.sechand.SechandType;
import work.huangxin.share.service.SechandBuyGoodsService;
import work.huangxin.share.service.SechandGoodsService;
import work.huangxin.share.service.SechandTypeService;
import work.huangxin.share.service.impl.MinioSysFileServiceImpl;
import work.huangxin.share.util.RedisUtil;
import work.huangxin.share.util.ThreadLocalUtil;
import work.huangxin.share.util.status.BaseResponse;
import work.huangxin.share.util.status.CodeEnum;
import work.huangxin.share.util.status.ResponseData;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author 季台星
 * @Date 2023 04 01 15 23
 * 后台管理二手市场
 */
@RestController
@RequestMapping("/wx/admin/api/sechand")
public class AdminSechandController {
    @Autowired
    private SechandGoodsService sechandGoodsService;

    @Autowired
    private SechandBuyGoodsService sechandBuyGoodsService;

    @Autowired
    private MinioSysFileServiceImpl minioSysFileService;

    @Autowired
    private SechandTypeService sechandTypeService;

    /**
     * 文件上次线程池
     */
    @Autowired
    @Qualifier("fileThreadPool")
    private ThreadPoolExecutor fileThreadPool;


    /**
     * 获得所有二手市场商品
     * @param request
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping("/getGoodsList")
    public BaseResponse getSechandGoodsList(HttpServletRequest request,
                                            @RequestParam("pageNo") Integer pageNo,
                                            @RequestParam("pageSize") Integer pageSize){
        PageInfo<SechandGoods> sechandGoodsList = sechandGoodsService.selectPageSechandGoodsList(pageNo,pageSize);
        if (Objects.isNull(sechandGoodsList)){
            return ResponseData.error(CodeEnum.NOT_FOUND);
        }
        return ResponseData.success(sechandGoodsList);
    }

    /**
     * 删除商品
     * @param goodsId
     * @return
     */
//    @PostMapping("/deleteGoods")
//    public BaseResponse deleteSechandGoodsList(@RequestParam("goodsId") Integer goodsId){
//        if (null == goodsId){
//            return ResponseData.error(CodeEnum.BODY_NOT_MATCH);
//        }
//        int i = sechandGoodsService.deleteSechandGoods(goodsId);
//        if (i <= 0){
//            return ResponseData.error(400, "删除商品失败，请联系开发者");
//        }
//        return ResponseData.success();
//    }

    @PostMapping("/delete/{goodsId}")
    public BaseResponse deleteSechandGoodsList(@PathVariable("goodsId") Integer goodsId){
        if (null == goodsId){
            return ResponseData.error(CodeEnum.BODY_NOT_MATCH);
        }
        int i = sechandGoodsService.deleteSechandGoods(goodsId);
        if (i <= 0){
            return ResponseData.error(400, "删除商品失败，请联系开发者");
        }
        return ResponseData.success();
    }

    /**
     * 删除求购商品
     * @param goodsId
     * @return
     */
    @PostMapping("/deleteBuyGoods")
    public BaseResponse deleteSechandBuyGoodsList(@RequestParam("goodsId") Integer goodsId){
        if (null == goodsId){
            return ResponseData.error(CodeEnum.BODY_NOT_MATCH);
        }
        int i = sechandBuyGoodsService.deletedBuyGoods(goodsId);
        if (i <= 0){
            return ResponseData.error(400, "删除商品失败，请联系开发者");
        }
        return ResponseData.success();
    }
    /**
     * 获得所有求购商品
     */
    @GetMapping("/getBuyGoods")
    public BaseResponse getBuyGoodsList(@RequestParam Integer pageNo,
                                        @RequestParam Integer pageSize){
        PageInfo<SechandBuyGoods> sechandBuyGoodsPageInfo = sechandBuyGoodsService.selectPageSechandBuyGoodsList(pageNo, pageSize);
        if (Objects.isNull(sechandBuyGoodsPageInfo)){
            return ResponseData.error(CodeEnum.NOT_FOUND);
        }
        return ResponseData.success(sechandBuyGoodsPageInfo);
    }

    /**
     * 下架求购商品
     * @param goodsId
     * @return
     */
//    @PostMapping("/isBuyGoodsWithBuy")
//    public BaseResponse deleteSechandBuyGoods(@RequestParam("goodsId") Integer goodsId){
//        int i = sechandBuyGoodsService.deleteBuyGoodsByAdmin(goodsId);
//        if (i <= 0){
//            return ResponseData.error(CodeEnum.SIGNATURE_NOT_ALLOW);
//        }
//        return ResponseData.success();
//    }

    @PostMapping("/isBuyGoodsWithBuy")
    public BaseResponse deleteSechandBuyGoods(@RequestParam("goodsId") Integer goodsId,
                                              @RequestParam("hasBuied") Integer hasBuied){
        int i = sechandBuyGoodsService.deleteBuyGoodsByAdmin(goodsId, hasBuied);
        if (i <= 0){
            return ResponseData.error(CodeEnum.SIGNATURE_NOT_ALLOW);
        }
        return ResponseData.success();
    }

    /**
     * 管理员新增商品
     * @param
     * @param sechandGoods
     * @param request
     * 前端需要设置用户Id
     * @return
     */
//    @PostMapping("/saveGoods")
//    public BaseResponse uploadZip(@RequestPart(value = "file",required = false) MultipartFile file,
//                                  @RequestPart("secHandGoods") SechandGoods sechandGoods,
//                                  HttpServletRequest request) {
//        String sechandName = null;
//        UserAdminSys user = (UserAdminSys) request.getSession().getAttribute("admin");
//        try {
//            sechandName = minioSysFileService.uploadFileWithZip(file);
//            sechandGoods.setGoodsPhotos(sechandName);
//            sechandGoods.setUserId(Long.valueOf(user.getId()));
//            int i = sechandGoodsService.insertSechandGoods(sechandGoods);
//            if (i <= 0){
//                return ResponseData.error(CodeEnum.BODY_NOT_MATCH);
//            }
//            return ResponseData.success(sechandName);
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//    }

    @PostMapping("/saveGoods")
    public BaseResponse saveGoods(@RequestBody SechandGoods sechandGoods,
                                  HttpServletRequest request){
        UserAdminSys user = (UserAdminSys) request.getSession().getAttribute("admin");

        Long userId = ThreadLocalUtil.get();
        UserAdminSys adminSys = (UserAdminSys) redisUtil.get("admin:" + userId);

        sechandGoods.setUserId(Long.valueOf(user.getId()));
        if (Objects.isNull(sechandGoods) || Strings.isNullOrEmpty(sechandGoods.getGoodsPhotos())){
            return ResponseData.error(CodeEnum.BODY_NOT_MATCH);
        }
        int i = sechandGoodsService.insertSechandGoods(sechandGoods);
        if (i <= 0){
            return ResponseData.error(CodeEnum.BODY_NOT_MATCH);
        }
        return ResponseData.success();
    }

    @PostMapping("/uploadImage")
    public BaseResponse uploadZip(@RequestPart(value = "file",required = false) MultipartFile file) {
        String ossImageUrl = null;
        try {
            ossImageUrl = minioSysFileService.uploadFileWithZip(file);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return ResponseData.success(ossImageUrl);
    }
    @Autowired
    private RedisUtil redisUtil;
    @PostMapping("/updateGoods")
    public BaseResponse updateGoods(@RequestBody SechandGoods sechandGoods,
                                    HttpServletRequest request){
        WXSessionModel user = (WXSessionModel) request.getSession().getAttribute("user");
        Long userId = ThreadLocalUtil.get();
        WXSessionModel user1 = (WXSessionModel) redisUtil.get("user:" + userId);
        sechandGoods.setUserId(Long.valueOf(userId));

        sechandGoods.setUserId(Long.valueOf(user.getUserId()));
        if (Objects.isNull(sechandGoods) || Strings.isNullOrEmpty(sechandGoods.getGoodsPhotos())){
            return ResponseData.error(CodeEnum.BODY_NOT_MATCH);
        }
        int i = sechandGoodsService.updateSechandGoods(sechandGoods);
        if (i <= 0){
            return ResponseData.error(CodeEnum.BODY_NOT_MATCH);
        }
        return ResponseData.success();
    }

    @GetMapping("/getGoodsByType")
    public BaseResponse getGoodsByType(@RequestParam Integer pageNo,
                                       @RequestParam Integer pageSize,
                                       @RequestParam Integer typeId){
        PageInfo<SechandGoods> sechandGoodsPageInfo = sechandGoodsService.selectGoodByTypeId(pageNo,pageSize,typeId);
        return ResponseData.success(sechandGoodsPageInfo);
    }

    @GetMapping("/getList")
    public BaseResponse getList(){
        List<SechandType> sechandTypeList = sechandTypeService.getList();
        return ResponseData.success(sechandTypeList);
    }
    /**
     * 管理员修改商品信息
     *
     */
//    @PutMapping("/updateGoods")
//    public BaseResponse updateGoods(
//            @RequestPart("files") MultipartFile[] files,
//            //@RequestParam("secHandGoods") String jsonStr,
//            @RequestPart("secHandGoods") SechandGoods sechandGoods,
//            HttpServletRequest request) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
//        //SechandGoods sechandGoods = JSON.parseObject(jsonStr, SechandGoods.class);
////        UserAdminSys admin = (UserAdminSys) request.getSession().getAttribute("admin");
////        sechandGoods.setUserId(Long.valueOf(admin.getId()));
//        minioSysFileService.deleteFiles(sechandGoods.getGoodsPhotos());
//        //MultipartFile[] files = sechandGoods.getFiles();
//        //线程安全
//        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
//        CountDownLatch countDownLatch = new CountDownLatch(files.length);
//        for (int i = 0; i < files.length; i++) {
//            try {
//                MultipartFile file = files[i];
//                //TODO 使用CountDownLaunch或者ComplatableFuture或者Semaphore
//                //来完成多线程的文件上传
//                fileThreadPool.submit(() -> {
//                    try {
//                        String url = minioSysFileService.uploadFile(file);
//                        list.add(url);
//                    } catch (Exception e) {
//                        throw new RuntimeException(e);
//                    } finally {
//                        //表示一个文件已经被完成
//                        countDownLatch.countDown();
//                    }
//                });
//            } catch (Exception e) {
//                throw new RuntimeException(e);
//            }
//        }
//        try {
//            //阻塞直到所有的文件完成复制
//            countDownLatch.await();
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }
//        //统计每个文件的url
//        String photoUrls = String.join(",", list);
//        sechandGoods.setGoodsPhotos(photoUrls);
//        int isUpdate = sechandGoodsService.updateSechandGoods(sechandGoods);
//        //if (isUpdate == 0) {
//        //    return ResponseData.error(CodeEnum.BODY_NOT_MATCH);
//        //}
//        return ResponseData.success(sechandGoods);
//    }

    /**
     * 管理员上传求购商品
     * @param files
     * @param sechandBuyGoods
     * @param request
     * @return
     */

    @PostMapping("/saveBuyGoods")
    public BaseResponse saveGoodByUserId(
            @RequestPart("files") MultipartFile[] files,
            //@RequestParam("secHandGoods") String jsonStr,
            @RequestPart("secHandBuyGoods") SechandBuyGoods sechandBuyGoods,
            HttpServletRequest request) {
        WXSessionModel user = (WXSessionModel) request.getSession().getAttribute("user");

        Long userId = ThreadLocalUtil.get();
        WXSessionModel user1 = (WXSessionModel) redisUtil.get("user:" + userId);
        //SechandGoods sechandGoods = JSON.parseObject(jsonStr, SechandGoods.class);
        sechandBuyGoods.setUserId(Long.valueOf(user.getUserId()));
        //MultipartFile[] files = sechandGoods.getFiles();
        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
        CountDownLatch countDownLatch = new CountDownLatch(files.length);
        for (int i = 0; i < files.length; i++) {
            try {
                MultipartFile file = files[i];
                //TODO 使用CountDownLaunch或者ComplatableFuture或者Semaphore
                //来完成多线程的文件上传
                fileThreadPool.submit(() -> {
                    try {
                        String url = minioSysFileService.uploadFile(file);
                        list.add(url);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    } finally {
                        //表示一个文件已经被完成
                        countDownLatch.countDown();
                    }
                });
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        try {
            //阻塞直到所有的文件完成复制
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //统计每个文件的url
        String photoUrls = String.join(",", list);
        sechandBuyGoods.setBuyGoodsPhotos(photoUrls);
        sechandBuyGoodsService.insertSechandBuyGoods(sechandBuyGoods);
        return ResponseData.success(sechandBuyGoods);
    }

    /**
     *更新求购商品
     */

    @PutMapping("/updateBuyGoods")
    public BaseResponse updateGoods(
            @RequestPart("files") MultipartFile[] files,
            //@RequestParam("secHandGoods") String jsonStr,
            @RequestPart("secHandBuyGoods") SechandBuyGoods sechandBuyGoods,
            HttpServletRequest request) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        //SechandGoods sechandGoods = JSON.parseObject(jsonStr, SechandGoods.class);
        minioSysFileService.deleteFiles(sechandBuyGoods.getBuyGoodsPhotos());
        //MultipartFile[] files = sechandGoods.getFiles();
        //线程安全
        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
        CountDownLatch countDownLatch = new CountDownLatch(files.length);
        for (int i = 0; i < files.length; i++) {
            try {
                MultipartFile file = files[i];
                //TODO 使用CountDownLaunch或者ComplatableFuture或者Semaphore
                //来完成多线程的文件上传
                fileThreadPool.submit(() -> {
                    try {
                        String url = minioSysFileService.uploadFile(file);
                        list.add(url);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    } finally {
                        //表示一个文件已经被完成
                        countDownLatch.countDown();
                    }
                });
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        try {
            //阻塞直到所有的文件完成复制
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //统计每个文件的url
        String photoUrls = String.join(",", list);
        sechandBuyGoods.setBuyGoodsPhotos(photoUrls);
        int isUpdate = sechandBuyGoodsService.updateSechandGoods(sechandBuyGoods);
        if (isUpdate <= 0) {
            return ResponseData.error(CodeEnum.BODY_NOT_MATCH);

        }
        return ResponseData.success();
    }
    @PostMapping("isBuyGoods")
    public BaseResponse isBuyGoods(@RequestParam("goodsId") Integer goodsId,
                                   @RequestParam("isBuy") Integer isBuy){

        int i = sechandGoodsService.updateGoodsIsBuy(isBuy, Long.valueOf(goodsId));
        if (i <= 0){
            return ResponseData.error(CodeEnum.NOT_FOUND);
        }
        return ResponseData.success();
    }
}
